home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / c / hce.lha / HCE / HCESource / TOP / Source / peep3.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-02  |  12.3 KB  |  553 lines

  1. /* Copyright (c) 1988,1991 by Sozobon, Limited.  Author: Tony Andrews
  2.  *
  3.  * Permission is granted to anyone to use this software for any purpose
  4.  * on any computer system, and to redistribute it freely, with the
  5.  * following restrictions:
  6.  * 1) No charge may be made other than reasonable charges for reproduction.
  7.  * 2) Modified versions must be clearly marked as such.
  8.  * 3) The authors are not responsible for any harmful consequences
  9.  *    of using this software, even if they result from defects in it.
  10.  */
  11.  
  12. /*
  13.  * 3-instruction peephole optimizations
  14.  */
  15.  
  16. #include "top.h"
  17.  
  18.  
  19. /*
  20.  * ipeep3(bp, ip) - look for 3-instruction optimizations at the given inst.
  21.  */
  22. static bool
  23. ipeep3(bp, i1)
  24. register BLOCK    *bp;
  25. register INST    *i1;
  26. {
  27.     register INST    *i2 = i1->next;    /* the next instruction */
  28.     INST    *i3 = i1->next->next;    /* the third instruction */
  29.  
  30.     register int    op1 = i1->opcode;
  31.     register int    op2 = i2->opcode;
  32.     register int    op3 = i3->opcode;
  33.  
  34.     /*
  35.      *    move.l    Am, Dn        =>    lea    N(Am), Ao
  36.      *    add.l    #N, Dn
  37.      *    move.l    Dn, Ao
  38.      *
  39.      *    Also, Dn must be dead after the third instruction.
  40.      */
  41.     if ((op1 == MOVE) && (i1->flags & LENL) &&
  42.         (i1->src.amode == REG) &&
  43.         ISA(i1->src.areg) &&
  44.         (i1->dst.amode == REG) &&
  45.         ISD(i1->dst.areg)) {
  46.  
  47.         if (((op2 == ADD) || (op2 == ADDQ)) &&
  48.             (i2->flags & LENL) &&
  49.             (i2->src.amode == IMM) &&
  50.             DOK(i2->src.disp) &&
  51.             (i2->dst.amode == REG) &&
  52.             (i2->dst.areg == i1->dst.areg)) {
  53.  
  54.             if ((op3 == MOVE) && (i3->flags & LENL) &&
  55.                 (i3->src.amode == REG) &&
  56.                 (i3->src.areg == i1->dst.areg) &&
  57.                 (i3->dst.amode == REG) &&
  58.                 ISA(i3->dst.areg) &&
  59.                 ((i3->live & RM(i3->src.areg)) == 0)) {
  60.  
  61.                 /*
  62.                  * rewrite i1 and delete i2 and i3
  63.                  */
  64.                 i1->opcode = LEA;
  65.                 i1->flags = 0;
  66.                 i1->dst = i3->dst;
  67.  
  68.                 i1->src.amode = REGID;
  69.                 i1->src.disp = i2->src.disp;
  70.  
  71.                     delinst(bp, i2);
  72.                     delinst(bp, i3);
  73.                     DBG(printf("%d ", __LINE__))
  74.                     return TRUE;
  75.             }
  76.         }
  77.     }
  78.  
  79.     /*
  80.      *    move.l    Dm, Dn        =>    move.l    Dm, Ao
  81.      *    add.l    #N, Dn            lea    N(Ao), Ao
  82.      *    move.l    Dn, Ao
  83.      *
  84.      *    Also, Dn must be dead after the third instruction.
  85.      */
  86.     if ((op1 == MOVE) && (i1->flags & LENL) &&
  87.         (i1->src.amode == REG) &&
  88.         ISD(i1->src.areg) &&
  89.         (i1->dst.amode == REG) &&
  90.         ISD(i1->dst.areg)) {
  91.  
  92.         if (((op2 == ADD) || (op2 == ADDQ)) &&
  93.             (i2->flags & LENL) &&
  94.             (i2->src.amode == IMM) &&
  95.             DOK(i2->src.disp) &&
  96.             (i2->dst.amode == REG) &&
  97.             (i2->dst.areg == i1->dst.areg)) {
  98.  
  99.             if ((op3 == MOVE) && (i3->flags & LENL) &&
  100.                 (i3->src.amode == REG) &&
  101.                 (i3->src.areg == i1->dst.areg) &&
  102.                 (i3->dst.amode == REG) &&
  103.                 ISA(i3->dst.areg) &&
  104.                 ((i3->live & RM(i3->src.areg)) == 0)) {
  105.  
  106.                 /*
  107.                  * rewrite i1 and i2 and delete i3
  108.                  */
  109.                 i1->dst.areg = i3->dst.areg;
  110.                 
  111.                 i2->opcode = LEA;
  112.                 i2->flags = 0;
  113.                 i2->dst = i3->dst;
  114.  
  115.                 i2->src.amode = REGID;
  116.                 i2->src.areg = i2->dst.areg;
  117.                 i2->src.disp = i2->src.disp;
  118.  
  119.                     delinst(bp, i3);
  120.                     DBG(printf("%d ", __LINE__))
  121.                     return TRUE;
  122.             }
  123.         }
  124.     }
  125.  
  126.     /*
  127.      *    move.l    Am, Dn        =>    lea    -N(Am), Ao
  128.      *    sub.l    #N, Dn
  129.      *    move.l    Dn, Ao
  130.      *
  131.      *    Also, Dn must be dead after the third instruction.
  132.      */
  133.     if ((op1 == MOVE) && (i1->flags & LENL) &&
  134.         (i1->src.amode == REG) &&
  135.         ISA(i1->src.areg) &&
  136.         (i1->dst.amode == REG) &&
  137.         ISD(i1->dst.areg)) {
  138.  
  139.         if (((op2 == SUB) || (op2 == ADDQ)) &&
  140.             (i2->flags & LENL) &&
  141.             (i2->src.amode == IMM) &&
  142.             DOK(i2->src.disp) &&
  143.             (i2->dst.amode == REG) &&
  144.             (i2->dst.areg == i1->dst.areg)) {
  145.  
  146.             if ((op3 == MOVE) && (i3->flags & LENL) &&
  147.                 (i3->src.amode == REG) &&
  148.                 (i3->src.areg == i1->dst.areg) &&
  149.                 (i3->dst.amode == REG) &&
  150.                 ISA(i3->dst.areg) &&
  151.                 ((i3->live & RM(i3->src.areg)) == 0)) {
  152.  
  153.                 /*
  154.                  * rewrite i1 and delete i2 and i3
  155.                  */
  156.                 i1->opcode = LEA;
  157.                 i1->flags = 0;
  158.                 i1->dst = i3->dst;
  159.  
  160.                 i1->src.amode = REGID;
  161.                 i1->src.disp = -i2->src.disp;
  162.  
  163.                     delinst(bp, i2);
  164.                     delinst(bp, i3);
  165.                     DBG(printf("%d ", __LINE__))
  166.                     return TRUE;
  167.             }
  168.         }
  169.     }
  170.  
  171.     /*
  172.      *    move.l    Am, Dn        =>    lea    0(Am, Do), Ap
  173.      *    add.x    Do, Dn
  174.      *    move.l    Dn, Ap
  175.      *
  176.      *    The second instruction can be either a word or long add.
  177.      *    Also, Dn must be dead after the third instruction.
  178.      */
  179.     if ((op1 == MOVE) && (i1->flags & LENL) &&
  180.         (i1->src.amode == REG) &&
  181.         ISA(i1->src.areg) &&
  182.         (i1->dst.amode == REG) &&
  183.         ISD(i1->dst.areg)) {
  184.  
  185.         if (((op2 == ADD) || (op2 == ADDQ)) &&
  186.             (i2->flags & (LENL|LENW)) &&
  187.             (i2->src.amode == REG) &&
  188.             ISD(i2->src.areg) && (i1->dst.areg != i2->src.areg) &&
  189.             (i2->dst.amode == REG) &&
  190.             (i2->dst.areg == i1->dst.areg)) {
  191.  
  192.             if ((op3 == MOVE) && (i3->flags & LENL) &&
  193.                 (i3->src.amode == REG) &&
  194.                 (i3->src.areg == i1->dst.areg) &&
  195.                 (i3->dst.amode == REG) &&
  196.                 ISA(i3->dst.areg) &&
  197.                 ((i3->live & RM(i3->src.areg)) == 0)) {
  198.  
  199.                 /*
  200.                  * rewrite i1 and delete i2 and i3
  201.                  */
  202.                 i1->opcode = LEA;
  203.                 i1->flags = 0;
  204.                 i1->dst = i3->dst;
  205.  
  206.                 i1->src.amode = REGIDX;
  207.                 if (i2->flags & LENL)
  208.                     i1->src.amode |= XLONG;
  209.                 i1->src.ireg = i2->src.areg;
  210.                 i1->src.disp = 0;
  211.  
  212.                     delinst(bp, i2);
  213.                     delinst(bp, i3);
  214.                     DBG(printf("%d ", __LINE__))
  215.                     return TRUE;
  216.             }
  217.         }
  218.     }
  219.  
  220.     /*
  221.      *    move.l    X(Am), Dn    =>    move.l    X(Am), Ao
  222.      *    add.l    #N, Dn
  223.      *    move.l    Dn, Ao            lea    N(Ao), Ao
  224.      *
  225.      *    Also, Dn must be dead after the third instruction.
  226.      */
  227.     if ((op1 == MOVE) && (i1->flags & LENL) &&
  228.         (i1->src.amode == REGI || i1->src.amode == REGID) &&
  229.         (i1->dst.amode == REG) &&
  230.         ISD(i1->dst.areg)) {
  231.  
  232.         if (((op2 == ADD) || (op2 == ADDQ)) &&
  233.             (i2->flags & LENL) &&
  234.             (i2->src.amode == IMM) &&
  235.             DOK(i2->src.disp) &&
  236.             (i2->dst.amode == REG) &&
  237.             (i2->dst.areg == i1->dst.areg)) {
  238.  
  239.             if ((op3 == MOVE) && (i3->flags & LENL) &&
  240.                 (i3->src.amode == REG) &&
  241.                 (i3->src.areg == i1->dst.areg) &&
  242.                 (i3->dst.amode == REG) &&
  243.                 ISA(i3->dst.areg) &&
  244.                 ((i3->live & RM(i3->src.areg)) == 0)) {
  245.  
  246.                 /*
  247.                  * rewrite i1 and i3 and delete i2
  248.                  */
  249.                 i1->dst = i3->dst;
  250.  
  251.                 i3->opcode = LEA;
  252.                 i3->flags = 0;
  253.                 i3->src.amode = REGID;
  254.                 i3->src.areg = i3->dst.areg;
  255.                 i3->src.disp = i2->src.disp;
  256.  
  257.                     delinst(bp, i2);
  258.                     DBG(printf("%d ", __LINE__))
  259.                     return TRUE;
  260.             }
  261.         }
  262.     }
  263.  
  264.     /*
  265.      *    move.x    X, Dn        =>    move.x    X, Do
  266.      *    ext.y    Dn            ext.y    Do
  267.      *    move.y    Dn, Do
  268.      *
  269.      *    Where Dn is dead.
  270.      */
  271.     if ((op1 == MOVE)&&(op2 == EXT)&&(op3 == MOVE)&&
  272.         (i1->dst.amode == REG) && ISD(i1->dst.areg) &&
  273.         (i2->src.amode == REG) && (i3->src.amode == REG) &&
  274.         (i3->dst.amode == REG) && ISD(i3->dst.areg) &&
  275.         (i1->dst.areg == i2->src.areg) && (i1->dst.areg == i3->src.areg) &&
  276.         (i2->flags == i3->flags)) {
  277.  
  278.         if ((i3->live & RM(i3->src.areg)) == 0) {
  279.             i1->dst.areg = i3->dst.areg;
  280.             i2->src.areg = i3->dst.areg;
  281.  
  282.                 delinst(bp, i3);
  283.                 DBG(printf("%d ", __LINE__))
  284.                 return TRUE;
  285.         }
  286.     }
  287.  
  288.     /*
  289.      *    move.l    X, Dm        =>    move.l    X, An
  290.      *    INST                INST
  291.      *    move.l    Dm, An            ...deleted...
  292.      *
  293.      *    where INST doesn't modify Dm, and Dm is dead after i3
  294.      */
  295.     if ((op1 == MOVE) && (op3 == MOVE) &&
  296.         (i1->dst.amode == REG) && ISD(i1->dst.areg) &&
  297.         (i3->src.amode == REG) && (i1->dst.areg == i3->src.areg) &&
  298.         (i3->dst.amode == REG) && ISA(i3->dst.areg) &&
  299.  
  300. /* ADDED BY TETISOFT
  301.  * Avoid move.l (a0),d0 => move.l (a0),a0
  302.  *     addq.l #1,(a0)    addq.l #1,(a0)
  303.  *     move.l d0,a0
  304.  */        !((i1->src.amode == REGI) && (uses(i2, i1->src.areg)) &&
  305.                      (i1->src.areg == i3->dst.areg)) &&
  306.  
  307.         !uses(i2, i3->src.areg)) {
  308.  
  309.         if ((i3->live & i3->src.areg) == 0) {
  310.             i1->dst.areg = i3->dst.areg;
  311.             delinst(bp, i3);
  312.  
  313.                 DBG(printf("%d ", __LINE__))
  314.             return TRUE;
  315.         }
  316.     }
  317.  
  318.     /*
  319.      *    move.l    Am, An            ...deleted...
  320.      *    addq.l    #1, Am            ...deleted...
  321.      *    ... stuff ...            ... stuff ...
  322.      *    ???.b    ..(An)..    =>    ???.b    ..(Am)+..
  323.      *
  324.      *    An must be dead after the last instruction. Nothing in
  325.      *    "stuff" can modify Am.
  326.      */
  327.     if ((op1 == MOVE) && (i1->flags & LENL) &&
  328.         (i1->src.amode == REG) && ISA(i1->src.areg) &&
  329.         (i1->dst.amode == REG) && ISA(i1->dst.areg)) {
  330.  
  331.         int    rm = i1->src.areg;
  332.         int    rn = i1->dst.areg;
  333.  
  334.         if (((op2 == ADD) || (op2 == ADDQ)) &&
  335.             (i2->flags & LENL) &&
  336.             (i2->src.amode == IMM) && (i2->src.disp == 1) &&
  337.             (i2->dst.amode == REG) &&
  338.             (i2->dst.areg == rm)) {
  339.  
  340.             while (i3 != NULL) {
  341.                 if (sets(i3, rm))
  342.                     goto end7;
  343.  
  344.                 if (i3->src.amode==REGI && i3->src.areg==rn) {
  345.                     if (i3->live & RM(rn))
  346.                         goto end7;
  347.  
  348.                     if ((i3->flags & LENB) == 0)
  349.                         goto end7;
  350.  
  351.                     i3->src.amode |= INC;
  352.                     i3->src.areg = rm;
  353.  
  354.                         delinst(bp, i1);
  355.                         delinst(bp, i2);
  356.                         DBG(printf("%d ", __LINE__))
  357.                         return TRUE;
  358.                 }
  359.                 if (i3->dst.amode==REGI && i3->dst.areg==rn) {
  360.                     if (i3->live & RM(rn))
  361.                         goto end7;
  362.  
  363.                     if ((i3->flags & LENB) == 0)
  364.                         goto end7;
  365.  
  366.                     i3->dst.amode |= INC;
  367.                     i3->dst.areg = rm;
  368.  
  369.                         delinst(bp, i1);
  370.                         delinst(bp, i2);
  371.                         DBG(printf("%d ", __LINE__))
  372.                         return TRUE;
  373.                 }
  374.  
  375.                 if (i3->next == NULL)
  376.                     goto end7;
  377.                 else
  378.                     i3 = i3->next;
  379.  
  380.             }
  381.         }
  382.     }
  383. end7:
  384.  
  385.     /*
  386.      *    move.l    Am, An
  387.      *    addq.l    #2, Am
  388.      *    ... stuff ...
  389.      *    ???.w    ..(An)..    =>    ???.w    ..(Am)+..
  390.      *
  391.      *    An must be dead after the last instruction. Nothing in
  392.      *    "stuff" can modify Am.
  393.      */
  394.     if ((op1 == MOVE) && (i1->flags & LENL) &&
  395.         (i1->src.amode == REG) && ISA(i1->src.areg) &&
  396.         (i1->dst.amode == REG) && ISA(i1->dst.areg)) {
  397.  
  398.         int    rm = i1->src.areg;
  399.         int    rn = i1->dst.areg;
  400.  
  401.         if (((op2 == ADD) || (op2 == ADDQ)) &&
  402.             (i2->flags & LENL) &&
  403.             (i2->src.amode == IMM) && (i2->src.disp == 2) &&
  404.             (i2->dst.amode == REG) &&
  405.             (i2->dst.areg == rm)) {
  406.  
  407.             while (i3 != NULL) {
  408.                 if (sets(i3, rm))
  409.                     goto end9;
  410.  
  411.                 if (i3->src.amode==REGI && i3->src.areg==rn) {
  412.                     if (i3->live & RM(rn))
  413.                         goto end9;
  414.  
  415.                     if ((i3->flags & LENW) == 0)
  416.                         goto end9;
  417.  
  418.                     i3->src.amode |= INC;
  419.                     i3->src.areg = rm;
  420.  
  421.                         delinst(bp, i1);
  422.                         delinst(bp, i2);
  423.                         DBG(printf("%d ", __LINE__))
  424.                         return TRUE;
  425.                 }
  426.                 if (i3->dst.amode==REGI && i3->dst.areg==rn) {
  427.                     if (i3->live & RM(rn))
  428.                         goto end9;
  429.  
  430.                     if ((i3->flags & LENW) == 0)
  431.                         goto end9;
  432.  
  433.                     i3->dst.amode |= INC;
  434.                     i3->dst.areg = rm;
  435.  
  436.                         delinst(bp, i1);
  437.                         delinst(bp, i2);
  438.                         DBG(printf("%d ", __LINE__))
  439.                         return TRUE;
  440.                 }
  441.  
  442.                 if (i3->next == NULL)
  443.                     goto end9;
  444.                 else
  445.                     i3 = i3->next;
  446.  
  447.             }
  448.         }
  449.     }
  450. end9:
  451.  
  452.     /*
  453.      *    move.l    Am, An
  454.      *    addq.l    #4, Am
  455.      *    ... stuff ...
  456.      *    ???.l    ..(An)..    =>    ???.l    ..(Am)+..
  457.      *
  458.      *    An must be dead after the last instruction. Nothing in
  459.      *    "stuff" can modify Am.
  460.      */
  461.     if ((op1 == MOVE) && (i1->flags & LENL) &&
  462.         (i1->src.amode == REG) && ISA(i1->src.areg) &&
  463.         (i1->dst.amode == REG) && ISA(i1->dst.areg)) {
  464.  
  465.         int    rm = i1->src.areg;
  466.         int    rn = i1->dst.areg;
  467.  
  468.         if (((op2 == ADD) || (op2 == ADDQ)) &&
  469.             (i2->flags & LENL) &&
  470.             (i2->src.amode == IMM) && (i2->src.disp == 4) &&
  471.             (i2->dst.amode == REG) &&
  472.             (i2->dst.areg == rm)) {
  473.  
  474.             while (i3 != NULL) {
  475.                 if (sets(i3, rm))
  476.                     goto end11;
  477.  
  478.                 if (i3->src.amode==REGI && i3->src.areg==rn) {
  479.                     if (i3->live & RM(rn))
  480.                         goto end11;
  481.  
  482.                     if ((i3->flags & LENL) == 0)
  483.                         goto end11;
  484.  
  485.                     i3->src.amode |= INC;
  486.                     i3->src.areg = rm;
  487.  
  488.                         delinst(bp, i1);
  489.                         delinst(bp, i2);
  490.                         DBG(printf("%d ", __LINE__))
  491.                         return TRUE;
  492.                 }
  493.                 if (i3->dst.amode==REGI && i3->dst.areg==rn) {
  494.                     if (i3->live & RM(rn))
  495.                         goto end11;
  496.  
  497.                     if ((i3->flags & LENL) == 0)
  498.                         goto end11;
  499.  
  500.                     i3->dst.amode |= INC;
  501.                     i3->dst.areg = rm;
  502.  
  503.                         delinst(bp, i1);
  504.                         delinst(bp, i2);
  505.                         DBG(printf("%d ", __LINE__))
  506.                         return TRUE;
  507.                 }
  508.  
  509.                 if (i3->next == NULL)
  510.                     goto end11;
  511.                 else
  512.                     i3 = i3->next;
  513.  
  514.             }
  515.         }
  516.     }
  517. end11:
  518.  
  519.     return FALSE;
  520. }
  521.  
  522. /*
  523.  * peep3(bp) - scan blocks starting at 'bp'
  524.  */
  525. bool
  526. peep3(bp)
  527. register BLOCK    *bp;
  528. {
  529.     register INST    *ip;
  530.     register bool    changed = FALSE;
  531.  
  532.     DBG(printf("p3: "))
  533.     for (; bp != NULL ;bp = bp->next) {
  534.         ip = bp->first;
  535.         while (ip!=NULL && ip->next != NULL && ip->next->next != NULL) {
  536.             if (ipeep3(bp, ip)) {
  537.                 s_peep3++;
  538.                 bprep(bp);
  539.                 changed = TRUE;
  540.                 /*
  541.                  * If we had a match, then any instruction
  542.                  * could have been deleted, so the safe thing
  543.                  * to do is to go to the next block.
  544.                  */
  545.                 break;
  546.             } else
  547.                 ip = ip->next;
  548.         }
  549.     }
  550.     DBG(printf("\n"); fflush(stdout))
  551.     return changed;
  552. }
  553.